package com.eric.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eric.domain.dto.MaterialDto;
import com.eric.domain.dto.MaterialInDto;
import com.eric.domain.dto.MaterialInPhotoDto;
import com.eric.domain.po.Material;
import com.eric.domain.po.MaterialIn;
import com.eric.domain.po.MaterialInPhoto;
import com.eric.mapper.MaterialInMapper;
import com.eric.mapper.MaterialMapper;
import com.eric.service.*;
import com.eric.utils.FilesDownLoad;
import com.eric.utils.PublicTools;
import com.eric.utils.ServerBASEURL;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.DeleteJoinWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.eric.utils.Constant.PAGE_CURRENT;
import static com.eric.utils.Constant.PAGE_SIZE;

/**
 * <p>
 * 材料入库表 服务实现类
 * </p>
 *
 * @author 新哥
 * @since 2024-03-12
 */
@Service
@RequiredArgsConstructor
public class MaterialInServiceImpl extends MPJBaseServiceImpl<MaterialInMapper, MaterialIn> implements IMaterialInService {
    //    配置encode的前缀
    private final static String ENCODE_PREFIX="MATERIAL_IN";
    private final MaterialMapper materialMapper;
    //    用于创建服务器磁盘的文件夹
    SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");
    //    用于做图片文件的文件名
    SimpleDateFormat photoDf = new SimpleDateFormat("yyyyMMdd");

    SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");



    //   判断当前用户权限的布尔值,用于通过登录用户的权限，选择性地决定是否通过location查询数据
//    private final boolean ROLE_FLAG=PublicTools.checkLoginRole();

    @Value("${file.location}")
    String fileLocation;

    //     创建用于创建服务器磁盘文件夹
    String materialInPhotoPath="/materialInPhotos";
    //    调用materialPhotoService，用于存储图片
    private final IMaterialInPhotoService materialInPhotoService;

    //    通过userService获取到真是名称用于equipment中的create_by和last_update_by
    private final ISysUserService userService;
    //    最后需要操作material表
    private final IMaterialService materialService;

    private final ILocationService locationService;

    @Override
    @Transactional
    public SaResult saveOneService(MaterialInDto materialInDto, MultipartFile[] photoFiles, MultipartFile[] materialFiles, HttpServletRequest request) {

//        todo 这里有一个问题，就是photoFiles是材料进场表单的图片，而materialFiles是针对material数据的图片，是否不用这个图片？？？？前端可以实现
//        todo 还有，是否需要在materialIn数据库表中增加这个 material的id字段，方便后续增，删，改时同步修改material的数据

//       检查materialInDto中的String类型数据，并发回一个新的对象
        MaterialInDto materialInDtoTrim = checkDto(materialInDto);
        if(BeanUtil.isEmpty(materialInDtoTrim)){
            return SaResult.error("输入对象不能为空");
        }
        if (StrUtil.isBlank(materialInDtoTrim.getMaterialName())){
            return SaResult.error("材料名称不能为空");
        }
        if (StrUtil.isBlank(materialInDtoTrim.getBrand())){
            return SaResult.error("品牌名字不能为空");
        }
        if (materialInDtoTrim.getNumber()<=0){
            return SaResult.error("数量不能为空或者不能小于等于零");
        }
        if (StrUtil.isBlank(materialInDtoTrim.getModel())){
            return SaResult.error("材料型号不能为空");
        }

        String encode_suffix = RandomUtil.randomString(5).toUpperCase();
        String DateFormat = photoDf.format(new Date());
        String materialIn_code=ENCODE_PREFIX+ DateFormat+encode_suffix;
        materialInDtoTrim.setEncode(materialIn_code);

//        获取到当前登录用户的userId
        int userId = Integer.parseInt(StpUtil.getLoginId().toString());
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

//        把前端表单传来的MaterialInDto对象转换为MaterialIn对象
        MaterialIn materialIn = BeanUtil.copyProperties(materialInDtoTrim, MaterialIn.class);
        materialIn.setCreateBy(userService.getById(userId).getRealName());
        materialIn.setWarehouse(locationAddress);


//      把materialIn表单数据转换为materialDto类型数据
        MaterialDto materialDto = BeanUtil.copyProperties(materialIn, MaterialDto.class);
//        通过id获取到的warehouseInfo的name，设定为materialDto中的Location值
        materialDto.setLocation(locationAddress);
//        获取到的materialDto对象，应该把encode设置为Null
        materialDto.setEncode(null);
//        通过material_name获取到material对象
        MPJLambdaWrapper<Material>mpjLambdaWrapper=new MPJLambdaWrapper<Material>()
                .eq("material_name", materialIn.getMaterialName())
                .eq("brand", materialIn.getBrand())
                .eq("model", materialIn.getModel())
                .eq("location",materialIn.getWarehouse());
        Material materialInDb = materialMapper.selectOne(mpjLambdaWrapper);

        //        如果material表中已存在同名称，同品牌，同型号，同地址的材料，就把数量number增加上去就好了
        if (!BeanUtil.isEmpty(materialInDb)) {
            double numberInDb = materialInDb.getNumber();
            double numberInsert = materialDto.getNumber();
            numberInsert+=numberInDb;
            materialInDb.setNumber(numberInsert);
            materialMapper.updateById(materialInDb);
            materialIn.setMaterialId(materialInDb.getId());
        }
//       否则，就会把一条新的材料表数据存进Material表中
        else {
            materialDto.setLocation(materialIn.getWarehouse());
            materialDto.setCreateBy(null);
            SaResult saResult = materialService.saveMaterialService(materialDto, materialFiles, request);
            if (saResult.getCode()==200){
                MPJLambdaWrapper<Material>lambdaWrapperQueryDb=new MPJLambdaWrapper<Material>()
                        .eq(Material::getMaterialName, materialDto.getMaterialName())
                        .eq(Material::getBrand, materialDto.getBrand())
                        .eq(Material::getModel, materialDto.getModel())
                        .eq(Material::getLocation,materialDto.getLocation());
                Material material = materialMapper.selectOne(lambdaWrapperQueryDb);
//       materialIn对象存进数据库前，要获取到material的id
                materialIn.setMaterialId(material.getId());
            }
            else {
                return SaResult.error("失败！");
            }
        }

        double totalPrice =materialInDto.getPrice()*materialInDto.getNumber();
        materialIn.setTotalPrice(totalPrice);


//        如果存储成功，返回一个成功值，就查询获取得到一个material对象

        boolean save = save(materialIn);

//        当数据表存进后，   图片文件才存进硬盘中，图片地址存进数据库中
        if (photoFiles!=null&&save) {
            fileOperation(materialIn_code, photoFiles, request);
        }
        return SaResult.ok("succeed!");
    }


    //   关于进场材料表单修改的问题，这里的逻辑策略是，不能在这里修改，只能修改进场材料表单的数量，及图片，材料进场表单的数量修改后，应该同步修改material表中的数量
    @Override
    @Transactional
    public SaResult modifyOneService(MaterialInDto materialInDto, MultipartFile[] photoFiles, HttpServletRequest request, String[] photoList) {

        MaterialInDto checkedDto = checkDto(materialInDto);

        if (checkedDto.getId()==null||checkedDto.getId()<=0){
            return SaResult.error("id值不符合要求");
        }
        MaterialIn materialIn = query().eq("id", checkedDto.getId()).one();

        if (BeanUtil.isEmpty(materialIn)) {
            return SaResult.error("没有此表单，请核实");
        }

        if (!checkedDto.getEncode().equals(materialIn.getEncode())) {
            return SaResult.error("encode和数据库中的encode不匹配");
        }

//       前端已经带来了原先materialIn的一个number，就是originNumber
        Integer numberInMaterialIn =checkedDto.getOriginNumber();
//        获取传进来的对象中number的值
        double numberInForm = materialInDto.getNumber();

//        通过materialInDto中的materialId查询material表中的number
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .eq(Material::getId, materialIn.getMaterialId());
        Material materialDb = materialMapper.selectOne(wrapper);
        double numberInMaterial = materialDb.getNumber();
//        对于这三个number的逻辑问题
//       前端表单number和materialIn表中的number差值---num1
//        3-15=-12
        double num1=numberInForm-numberInMaterialIn;
//       1、 如果前端传来的数值比materialIn原来表单中的数值大，意味着number是增加的，所以应该把差值也增加到material表单中
        if(num1>0){
            numberInMaterial+=num1;
            materialDb.setNumber(numberInMaterial);
//         ***************************  修改material表单  **********************************
            materialMapper.updateById(materialDb);
        }
//        2、如果前端传来的数值比materialIn原来表单的数值小，两个值之间的差值<0 意味着number是减少的，但有分成两个部分

        if (num1<0){
//        2-1、如果差值比material表中的值大，就应该返回错误，material表中Number不应该为0
            if (-num1>materialDb.getNumber()){
                return SaResult.error("number错误");
            }
            //        2-2、如果差值比material表中的值小，那应该是material表中的Number值减去这个差值后的数，就是material表中number新的值
            else {
                numberInMaterial-=-num1;
                materialDb.setNumber(numberInMaterial);



//         ***************************  修改material表单  **********************************
                materialMapper.updateById(materialDb);


            }
        }
//        删除前端传进来的文件名的文件
        if (photoList!=null&&photoList.length>0){
            for (String photoUrl : photoList) {
//            1、截取“file/”后面的字符串
                String substring = photoUrl.substring(photoUrl.indexOf("e") + 2);
//            2、删除文件
                FileUtil.del(fileLocation + substring);
            }
            materialInPhotoService.deleteByPhotoUrlList(Arrays.asList(photoList));
        }
//        把新文件写入数据库
        if (photoFiles!=null){
            fileOperation(checkedDto.getEncode(),photoFiles,request);
        }

        //        获取登录用户id
        Object loginId = StpUtil.getLoginId();
        int userId = Integer.parseInt(loginId.toString());
        String realName = userService.getById(userId).getRealName();
//        MaterialIn materialInNew = BeanUtil.copyProperties(checkedDto, MaterialIn.class);
//        materialInNew.setLastUpdateBy(realName);


//        这里逻辑，仅仅是更新数量，还有图片，其它的不做修改，前端把其它input端锁死

        MaterialIn materialInOnlyNum=new MaterialIn();

        materialInOnlyNum.setId(checkedDto.getId());
        materialInOnlyNum.setNumber(checkedDto.getNumber());
        materialInOnlyNum.setDescription(checkedDto.getDescription());
        materialInOnlyNum.setLastUpdateBy(realName);
        materialInOnlyNum.setReceiveProject(checkedDto.getReceiveProject());
        materialInOnlyNum.setPrice(checkedDto.getPrice());
        materialInOnlyNum.setTotalPrice(checkedDto.getTotalPrice());

//    ************************   修改materialIn表单    ****************************
        boolean updated = updateById(materialInOnlyNum);
        return updated?SaResult.ok("修改成功"):SaResult.error("修改失败");
    }



    @Override
    @Transactional
    public SaResult deleteOneByIdService(Integer id) {
        if (id==null||id<=0){
            return SaResult.error("id参数错误");
        }
//        这里有逻辑，在删除一条记录时候，material中的Number数据应该也要修改
//        通过id获取materialIn对象
        MaterialIn materialIn = query().eq("id", id).one();

//        获取materialIn表单中的number
        double materialIn_Number = materialIn.getNumber();

//        获取到materialIn的materialName，通过这个name获取到material的name
        String materialIn_Name = materialIn.getMaterialName();
        String materialIn_Model = materialIn.getModel();
        String materialIn_Brand = materialIn.getBrand();
        String materialIn_warehouse = materialIn.getWarehouse();

//        通过materialName获取到查询条件,注意，这个Mater
        MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                .eq(Material::getModel,materialIn_Model)
                .eq(Material::getBrand,materialIn_Brand)
                .eq(Material::getMaterialName, materialIn_Name)
                .eq(Material::getLocation,materialIn_warehouse);
//      todo   获取到material对象 这里有一个问题需要解决，如果对应的一个material数据已经被删除，这里就是未Null,number就不会存在
        Material material = materialService.getOne(wrapper);

        if (!BeanUtil.isEmpty(material)) {
            //        获取到material对象中的number
            double material_Number = material.getNumber();
//        逻辑是，由于这是材料入库，删除调一条materialIn表单，意味着material中的number应减去materialIn表单中的materialInNumber
            material_Number-=materialIn_Number;
            material.setNumber(material_Number);

//        更新material
            materialMapper.updateById(material);
        }
//        material_in_photo同步删除
        DeleteJoinWrapper<MaterialIn>deleteJoinWrapper= JoinWrappers.delete(MaterialIn.class)
                .deleteAll()
                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)
                .eq(MaterialIn::getId,id);
        deleteJoin(deleteJoinWrapper);
        return SaResult.ok("succeed");
    }

    @Override
    @Transactional
    public SaResult deleteByIdsService(ArrayList<Integer> ids) {
//        这里有逻辑，在删除一条记录时候，material中的Number数据应该也要修改
        if (ids==null||ids.isEmpty()){
            return SaResult.error("id有误");
        }


        for (Integer id : ids) {
//        通过id获取materialIn对象
            MaterialIn materialIn = query().eq("id", id).one();
//        获取materialIn表单中的number
            double materialInNumber = materialIn.getNumber();
//        获取到materialIn的materialName，通过这个name获取到material的name
            String materialName = materialIn.getMaterialName();
//        通过materialName获取到查询条件
            MPJLambdaWrapper<Material>wrapper=new MPJLambdaWrapper<Material>()
                    .eq(Material::getMaterialName, materialName);
//        获取到material对象
            Material material = materialService.getOne(wrapper);
//        获取到material对象中的number
            double materialNumber = material.getNumber();
//        逻辑是，由于这是材料入库，删除调一条materialIn表单，意味着material中的number应减去materialIn表单中的materialInNumber
            materialNumber-=materialInNumber;
            material.setNumber(materialNumber);
//        更新material
            materialMapper.updateById(material);
//        material_in_photo同步删除
            DeleteJoinWrapper<MaterialIn>deleteJoinWrapper= JoinWrappers.delete(MaterialIn.class)
                    .deleteAll()
                    .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)
                    .eq(MaterialIn::getId,id);
            deleteJoin(deleteJoinWrapper);
        }
        return SaResult.ok("succeed");
    }

    @Override
    public SaResult getAllByPage(Integer current, Integer pageSize) {
        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }

        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        Page<MaterialInDto>page=new Page<>(current,pageSize);

        MPJLambdaWrapper<MaterialIn>wrapper = new MPJLambdaWrapper<MaterialIn>()
                .orderBy(true,false,"id")
                .selectAll(MaterialIn.class)
//                如果登录用户是sys:admin，sys:manager，sys:superAdmin，sys:coder，就不通过location查询
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)

                .orderByDesc(MaterialIn::getUpdateTime);


        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> materialInDtoList = materialInDtoPage.getRecords();


        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getOneByIdService(Integer id) {
        if (id==null||id<=0){
            return SaResult.error("id错误");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
                //                如果登录用户是sys:admin，sys:manager，sys:superAdmin，sys:coder，就不通过location查询
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
                .eq(MaterialIn::getId,id)
                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode);
        MaterialInDto materialInDto = selectJoinOne(MaterialInDto.class, wrapper);

        if(BeanUtil.isEmpty(materialInDto)){
            return SaResult.ok("没有此项记录！");
        }



//     这里是，获取到的materialInDto对象，应该把photoUrl的地址，拼接上服务器的地址，这样前端才能显示图片
        List<MaterialInPhoto> materialInPhotoList = materialInDto.getMaterialInPhotoList();



        if(materialInPhotoList.size()==1&&materialInPhotoList.get(0).getMaterialInEncode()==null){
            materialInPhotoList.remove(0);
            return SaResult.data(materialInDto);
        }
        else if (!BeanUtil.isEmpty(materialInPhotoList)){
            // 拼接服务器基础地址,直接在materialInPhotoList中的每个元素直接修改，
            for (MaterialInPhoto materialInPhoto : materialInPhotoList) {
                String originalUrl = materialInPhoto.getPhotoUrl();
                String newUrl = ServerBASEURL.BASEURL + originalUrl;
                materialInPhoto.setPhotoUrl(newUrl);
            }
            return SaResult.data(materialInDto);
        }
        else {
            return SaResult.data(materialInDto);
        }


    }

    @Override
    public SaResult getByBetweenTimesService(Date start, Date end, Integer current, Integer pageSize) {
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }
        if (BeanUtil.isEmpty(start) || BeanUtil.isEmpty(end)) {
            return SaResult.error("日期为空，请核实！");
        }
        if (end.before(start)) {
            Date temp;
            temp=start;
            start=end;
            end=temp;
        }
        String startFormat = timeFormat.format(start);
        String endFormat = timeFormat.format(end);

        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        Page<MaterialInDto>page=new Page<>(current,pageSize);
//       创建查询对象
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .apply("date_format(t.create_time,'%y%m%d') >= date_format('" +startFormat + "','%y%m%d')")
                .apply("date_format(t.create_time,'%y%m%d') <= date_format('" + endFormat + "','%y%m%d')")
//                如果登录用户是sys:admin，sys:manager，sys:superAdmin，sys:coder，就不通过location查询
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
                .orderByDesc(MaterialIn::getUpdateTime);
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

//   根据getByBetweenTimesService这个方法，获取所有数据行的条数

    @Override
    public SaResult getAllCountsByBetweenTimes(Date start, Date end) {
        if (BeanUtil.isEmpty(start) || BeanUtil.isEmpty(end)) {
            return SaResult.error("日期为空，请核实！");
        }
        if (end.before(start)) {
            Date temp;
            temp=start;
            start=end;
            end=temp;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        String startFormat = timeFormat.format(start);
        String endFormat = timeFormat.format(end);
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .select("count(id)")
                .apply("date_format(t.create_time,'%y%m%d') >= date_format('" +startFormat + "','%y%m%d')")
                .apply("date_format(t.create_time,'%y%m%d') <= date_format('" + endFormat + "','%y%m%d')")
//                如果登录用户是sys:admin，sys:manager，sys:superAdmin，sys:coder，就不通过location查询
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);
//        Long l = selectJoinCount(wrapper);
        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }

    @Override
    public void downloadFilesService(String[] files, HttpServletResponse response) throws IOException {
        FilesDownLoad.filesToZip(response,files,fileLocation);
    }

    //    这个方法和另外一个方法有点区别，这里是，前端传来得图片，也需要存进这个materialPhoto里面
    @Override
    @Transactional
    public SaResult saveNewOneService(MaterialInDto materialInDto, MultipartFile[] photoFiles, HttpServletRequest request) throws IOException {
//        todo 这里有一个问题，就是photoFiles是材料进场表单的图片，而materialFiles是针对material数据的图片，是否不用这个图片？？？？前端可以实现
//        todo 还有，是否需要在materialIn数据库表中增加这个 material的id字段，方便后续增，删，改时同步修改material的数据


//        TODO 这里有一个很大问题，就是这个photoFiles是用了2次，造成第一次可以使用，第二次就报错了
//        TODO 目前得解决办法是，material表没有图片，需要图片时候，再修改，前端传来得图片是给了materialIn使用



//        MultipartFile[] newIn=new MultipartFile[photoFiles.length];
//
//        for (int i = 0; i < photoFiles.length; i++) {
//            byte[] bytes = photoFiles[i].getBytes();
//            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
//            MockMultipartFile mockMultipartFile = new MockMultipartFile(RandomUtil.randomString(3), byteArrayInputStream);
//            newIn[i] = mockMultipartFile;
//        }



//       检查materialInDto中的String类型数据，并发回一个新的对象
        MaterialInDto materialInDtoTrim = checkDto(materialInDto);
        if(BeanUtil.isEmpty(materialInDtoTrim)){
            return SaResult.error("输入对象不能为空");
        }
        if (StrUtil.isBlank(materialInDtoTrim.getMaterialName())){
            return SaResult.error("材料名称不能为空");
        }
        if (StrUtil.isBlank(materialInDtoTrim.getBrand())){
            return SaResult.error("品牌名字不能为空");
        }
        if (materialInDtoTrim.getNumber()<=0){
            return SaResult.error("数量不能为空或者不能小于等于零");
        }
        if (StrUtil.isBlank(materialInDtoTrim.getModel())){
            return SaResult.error("材料型号不能为空");
        }

        String encode_suffix = RandomUtil.randomString(5).toUpperCase();
        String DateFormat = photoDf.format(new Date());
        String materialIn_code=ENCODE_PREFIX+ DateFormat+encode_suffix;
        materialInDtoTrim.setEncode(materialIn_code);

//        获取到当前登录用户的userId
        int userId = Integer.parseInt(StpUtil.getLoginId().toString());

        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

//        把前端表单传来的MaterialInDto对象转换为MaterialIn对象
        MaterialIn materialIn = BeanUtil.copyProperties(materialInDtoTrim, MaterialIn.class);
        materialIn.setCreateBy(userService.getById(userId).getRealName());
        materialIn.setWarehouse(locationAddress);

//      把materialIn表单数据转换为materialDto类型数据
        MaterialDto materialDto = BeanUtil.copyProperties(materialIn, MaterialDto.class);
//        通过id获取到的warehouseInfo的name，设定为materialDto中的Location值
        materialDto.setLocation(locationAddress);
//        获取到的materialDto对象，应该把encode设置为Null
        materialDto.setEncode(null);
//        通过material_name获取到material对象
        MPJLambdaWrapper<Material>mpjLambdaWrapper=new MPJLambdaWrapper<Material>()
                .eq("material_name", materialIn.getMaterialName())
                .eq("brand", materialIn.getBrand())
                .eq("model", materialIn.getModel())
                .eq("location",materialIn.getWarehouse());
        Material materialInDb = materialMapper.selectOne(mpjLambdaWrapper);

        //        如果material表中已存在同名称，同品牌，同型号，同地址的材料，就把数量number增加上去就好了
        if (!BeanUtil.isEmpty(materialInDb)) {
            double numberInDb = materialInDb.getNumber();
            double numberInsert = materialDto.getNumber();
            numberInsert+=numberInDb;
            materialInDb.setNumber(numberInsert);
            materialMapper.updateById(materialInDb);
            materialIn.setMaterialId(materialInDb.getId());
        }
//       否则，就会把一条新的材料表数据存进Material表中
        else {
            materialDto.setLocation(materialIn.getWarehouse());
            materialDto.setCreateBy(null);
            SaResult saResult = materialService.saveMaterialService(materialDto, null, request);
            if (saResult.getCode()==200){
                MPJLambdaWrapper<Material>lambdaWrapperQueryDb=new MPJLambdaWrapper<Material>()
                        .eq(Material::getMaterialName, materialDto.getMaterialName())
                        .eq(Material::getBrand, materialDto.getBrand())
                        .eq(Material::getModel, materialDto.getModel())
                        .eq(Material::getLocation,materialDto.getLocation());
                Material material = materialMapper.selectOne(lambdaWrapperQueryDb);
//       materialIn对象存进数据库前，要获取到material的id
                materialIn.setMaterialId(material.getId());
            }
            else {
                return SaResult.error("失败！");
            }
        }
        //        如果存储成功，返回一个成功值，就查询获取得到一个material对象

        double  totalPrince= (double) Math.round(materialIn.getPrice() * materialIn.getNumber() * 100) /100 ;
        materialIn.setTotalPrice(totalPrince);

        boolean save = save(materialIn);

//     todo   当数据表存进后，   图片文件才存进硬盘中，图片地址存进数据库中 materialIn表单图片不存储
        if (photoFiles!=null&&save) {
            fileOperation(materialIn_code, photoFiles, request);
        }
        return SaResult.ok("succeed!");
    }

    @Override
    public SaResult getMaterialInListByMaterialId(boolean timeStatus, Integer materialId,Integer current,Integer pageSize,String projectName,Date start, Date end) {
        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }

        String startFormat =null;
        String endFormat=null;
        if (StrUtil.isBlank(projectName)){
            projectName=null;
        }

        if (StrUtil.isBlank(projectName)){
            projectName=null;
        }

        if (timeStatus){
            if (end.before(start)) {
                Date temp;
                temp=start;
                start=end;
                end=temp;
            }
            startFormat=timeFormat.format(start);
            endFormat=timeFormat.format(end);
        }

        Page<MaterialInDto>page=new Page<>(current,pageSize);

        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .apply(timeStatus ,"date_format(t.create_time,'%y%m%d') >= date_format('" +startFormat + "','%y%m%d')")
                .apply(timeStatus,"date_format(t.create_time,'%y%m%d') <= date_format('" + endFormat + "','%y%m%d')")
                .eq(!StrUtil.isEmpty(projectName),MaterialIn::getReceiveProject,projectName)
                .eq(MaterialIn::getMaterialId, materialId);
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> materialInDtoList = materialInDtoPage.getRecords();


        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getMaterialInListCountByMaterialId(boolean timeStatus, Integer materialId, String projectName, Date start, Date end) {

        String startFormat =null;
        String endFormat=null;
        if (StrUtil.isBlank(projectName)){
            projectName=null;
        }


        if (timeStatus){
            if (end.before(start)) {
                Date temp;
                temp=start;
                start=end;
                end=temp;
            }
            startFormat = timeFormat.format(start);
            endFormat = timeFormat.format(end);
        }

        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .select("count(id)")
                .apply(timeStatus ,"date_format(t.create_time,'%y%m%d') >= date_format('" +startFormat + "','%y%m%d')")
                .apply(timeStatus,"date_format(t.create_time,'%y%m%d') <= date_format('" + endFormat + "','%y%m%d')")
                .eq(!StrUtil.isEmpty(projectName),MaterialIn::getReceiveProject,projectName)
                .eq(MaterialIn::getMaterialId, materialId);
        Long count = selectJoinOne(Long.class, wrapper);


        return SaResult.data(count);
    }


    @Override
    public SaResult getByCreateTimeService(Date createTime, Integer current, Integer pageSize) {
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }
//        当前端传来的是Date格式日期数据时，由于springMvc正常情况下是无法解析Date数据，需要转换，所以在controller的参数列表中
//       在Date参数前要加注解@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)，看下面：
//        (@DateTimeFormat(iso=DateTimeFormat.ISO.DATE) Date createTime, Integer current, Integer pageSize)
//        把前端传来的时间格式化为指定格式，这里指定格式是timeFormat模式，即在类中公共字段
//        SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String format = timeFormat.format(createTime);
//        创建分页对象
        Page<MaterialInDto>page=new Page<>(current,pageSize);
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
//        创建查询条件对象
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
//                记住，create_time前要加一个t.否则后面连接查询时，equip_transfer表和equip_transfer_photo表中都有create_time，会致使字段模糊，搞不清楚是那个表的create_time
//                这个是查指定日期的中的数据
                .apply("date_format(t.create_time,'%y%m%dd')=" + "date_format('" + format + "','%y%m%dd')")
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(MaterialIn::getUpdateTime);
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getByUpdateTimeService(Date updateTime, Integer current, Integer pageSize) {
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }
//        当前端传来的是Date格式日期数据时，由于springMvc正常情况下是无法解析Date数据，需要转换，所以在controller的参数列表中
//       在Date参数前要加注解@DateTimeFormat(iso=DateTimeFormat.ISO.DATE)，看下面：
//        (@DateTimeFormat(iso=DateTimeFormat.ISO.DATE) Date createTime, Integer current, Integer pageSize)
//        把前端传来的时间格式化为指定格式，这里指定格式是timeFormat模式，即在类中公共字段
//        SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String format = timeFormat.format(updateTime);
//        创建分页对象
        Page<MaterialInDto>page=new Page<>(current,pageSize);
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
//        创建查询条件对象
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
//                记住，create_time前要加一个t.否则后面连接查询时，equip_transfer表和equip_transfer_photo表中都有create_time，会致使字段模糊，搞不清楚是那个表的create_time
//                这个是查指定日期的中的数据
                .apply("date_format(t.update_time,'%y%m%dd')=" + "date_format('" + format + "','%y%m%dd')")
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc(MaterialIn::getUpdateTime);
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getByMaterialNameService(String materialName, Integer current, Integer pageSize) {
        String materialNameTrim = StrUtil.trim(materialName);
        if (StrUtil.isBlank(materialNameTrim)) {
            return SaResult.error("材料名不能为空");
        }
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        Page<MaterialInDto>page=new Page<>(current,pageSize);
//        创建查询条件对象
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("material_name",materialNameTrim)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)
//                .groupBy("create_time")
                .orderByDesc(MaterialIn::getUpdateTime);
        ;
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getByLastUpdateByService(String lastByName, Integer current, Integer pageSize) {
        if ( StrUtil.isBlank(StrUtil.trim(lastByName))){
            return SaResult.error("人名不能为空");
        }
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }

        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        Page<MaterialInDto>page=new Page<>(current,pageSize);

        //        创建查询条件对象
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("last_update_by",lastByName)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)
//                .groupBy("create_time")
                .orderByDesc("create_time")
                ;
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getByCreateByService(String createByName, Integer current, Integer pageSize) {
        if ( StrUtil.isBlank(StrUtil.trim(createByName))){
            return SaResult.error("人名不能为空");
        }
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }

        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        Page<MaterialInDto>page=new Page<>(current,pageSize);

        //        创建查询条件对象
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .eq("create_by",createByName)
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                下面的都是分页连接查询的普通步骤了
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)
//                .groupBy("create_time")
                .orderByDesc("create_time")
                ;
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getAllByMoon(Date moonDate, Integer current, Integer pageSize) {
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }
        String format = timeFormat.format(moonDate);
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        //        创建分页对象
        Page<MaterialInDto>page=new Page<>(current,pageSize);
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
//                记住，create_time前要加一个t.否则后面连接查询时，equip_transfer表和equip_transfer_photo表中都有create_time，会致使字段模糊，搞不清楚是那个表的create_time
//                这个是查指定日期的中的数据
//                queryWrapper.apply(" date_format(create_at,'%y%mm%') = date_format('" + withdrawRecord.getCreateAt() + "-01','%y%mm%')");

                .apply("date_format(t.create_time,'%y%m%')=" + "date_format('" + format + "','%y%m%')")
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
        Page<MaterialInDto> materialInDtoPage = selectJoinListPage(page, MaterialInDto.class, wrapper);
        List<MaterialInDto> records = materialInDtoPage.getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(records, MaterialInDto.class);
        return SaResult.data(materialInDtoList);
    }

    @Override
    public SaResult getByTypeName(String parentType, String childTypeName, Integer orderBy, Integer current, Integer pageSize) {
        if (StrUtil.isEmpty(parentType) && StrUtil.isEmpty(childTypeName)) {
            return SaResult.error("类型名称不能为空");
        }
        if (current==null||current<=0){
            current = PAGE_CURRENT;
        }
        if (pageSize==null||pageSize<=0){
            pageSize = PAGE_SIZE;
        }
        if (orderBy==null||orderBy<=0){
            return SaResult.error("orderBy值不能为空或者小于等于零！");
        }
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }

        boolean desc=true;
        boolean asc=false;
        if (orderBy!=1){
            desc=false;
            asc=true;
        }
        String fullTypeName = parentType+":"+childTypeName;
        Page<MaterialIn>page=new Page<>(current,pageSize);
        QueryWrapper<MaterialIn> wrapper=new QueryWrapper<>();
        wrapper.eq("type_name",fullTypeName)
                .eq(!PublicTools.checkLoginRole(),"warehouse",locationAddress)
                .orderByDesc(desc,"number")
                .orderByAsc(asc,"number");
        List<MaterialIn> materialInList = page(page, wrapper).getRecords();
        List<MaterialInDto> materialInDtoList = BeanUtil.copyToList(materialInList, MaterialInDto.class);
        return SaResult.data(materialInDtoList);

    }

    //    配合分页获取所有数据行接口，获取所有数据行的条数
    @Override
    public SaResult getAllCountsService() {
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址");
        }
        MPJLambdaWrapper<MaterialIn>wrapper=new MPJLambdaWrapper<MaterialIn>()
                .select( "count(id)")
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse, locationAddress);
        Long l = selectJoinOne(Long.class, wrapper);
        return SaResult.data(l);
    }

    @Override
    public SaResult getAllByMultifunctionNameService(String name, Integer current, Integer pageSize) {
        if ( StrUtil.isBlank(StrUtil.trim(name))){
            return SaResult.error("查询名不能为空");
        }
        if (current == null) {
            current = PAGE_CURRENT;
        }
        if (pageSize == null) {
            pageSize = PAGE_SIZE;
        }

        Page<MaterialInDto>page=new Page<>(current,pageSize);
        Set<MaterialInDto>finalResultList=new HashSet<>();
//        这个是判断当前用户是否已经分配了项目或者仓库，如果没有，返回一个错误
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址，不能查询！");
        }

        //        根据材料名查询
        MPJLambdaWrapper<MaterialIn>wrapperByMaterialName=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("material_name",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialDtoPageByMaterialName = selectJoinListPage(page, MaterialInDto.class, wrapperByMaterialName);
        List<MaterialInDto> materialDtoListByMaterialName =materialDtoPageByMaterialName.getRecords();
        if (!materialDtoListByMaterialName.isEmpty()){
            finalResultList.addAll(materialDtoListByMaterialName);
        }

        //        根据所在查询
        MPJLambdaWrapper<MaterialIn>wrapperByCreateBy=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("create_by",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialDtoPageByCreateBy = selectJoinListPage(page, MaterialInDto.class, wrapperByCreateBy);
        List<MaterialInDto> materialDtoListByCreateBy =materialDtoPageByCreateBy.getRecords();
        if (!materialDtoListByCreateBy.isEmpty()){
            finalResultList.addAll(materialDtoListByCreateBy);
        }


//    根据最后修改人查询

      /*  MPJLambdaWrapper<MaterialIn>wrapperByLastUpdateBy=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("last_update_by",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialDtoPageByLastUpdateBy = selectJoinListPage(page, MaterialInDto.class, wrapperByLastUpdateBy);
        List<MaterialInDto> materialDtoListByLastUpdateBy =materialDtoPageByLastUpdateBy.getRecords();
        if (!materialDtoListByLastUpdateBy.isEmpty()){
            finalResultList.addAll(materialDtoListByLastUpdateBy);
        }*/
        //    根据品牌查询

        MPJLambdaWrapper<MaterialIn>wrapperByBrand=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("brand",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialDtoPageByBrand = selectJoinListPage(page, MaterialInDto.class, wrapperByBrand);
        List<MaterialInDto> materialDtoListByBrand =materialDtoPageByBrand.getRecords();
        if (!materialDtoListByBrand.isEmpty()){
            finalResultList.addAll(materialDtoListByBrand);
        }

  /*      //    根据encode查询

        MPJLambdaWrapper<MaterialIn>wrapperByEncode=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("encode",name.toUpperCase())
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialDtoPageByEncode = selectJoinListPage(page, MaterialInDto.class, wrapperByEncode);
        List<MaterialInDto> materialDtoListByEncode =materialDtoPageByEncode.getRecords();
        if (!materialDtoListByEncode.isEmpty()){
            finalResultList.addAll(materialDtoListByEncode);
        }*/
        //    根据typeName查询

        MPJLambdaWrapper<MaterialIn>wrapperByTypeName=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("type_name",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress)
//                .groupBy("create_time")
                .orderByDesc("create_time");
//                .selectCollection(MaterialInPhoto.class,MaterialInDto::getMaterialInPhotoList)
//                .leftJoin(MaterialInPhoto.class,MaterialInPhoto::getMaterialInEncode,MaterialIn::getEncode)

        Page<MaterialInDto> materialDtoPageByTypeName = selectJoinListPage(page, MaterialInDto.class, wrapperByTypeName);
        List<MaterialInDto> materialDtoListByTypeName =materialDtoPageByTypeName.getRecords();
        if (!materialDtoListByTypeName.isEmpty()){
            finalResultList.addAll(materialDtoListByTypeName);
        }
        List<MaterialInDto>materialInDTOs=new ArrayList<>(finalResultList);


        //        对List内部元素重新按照创建时间从晚到早重新排序
        materialInDTOs.sort(new Comparator<MaterialInDto>() {
            @Override
            public int compare(MaterialInDto o1, MaterialInDto o2) {
                Date createTime1 = o1.getUpdateTime();
                Date createTime2 = o2.getUpdateTime();
                return createTime2.compareTo(createTime1);
            }
        });



        return SaResult.data(materialInDTOs);
    }

    @Override
    public SaResult getAllCountsByMultifunctionNameService(String name, Integer current, Integer pageSize) {
        if ( StrUtil.isBlank(StrUtil.trim(name))){
            return SaResult.error("查询名不能为空");
        }

        Set<MaterialIn> finalResultList=new HashSet<>();
//        这个是判断当前用户是否已经分配了项目或者仓库，如果没有，返回一个错误
        String locationAddress = locationService.getAllByLoginId();
        if (StrUtil.isBlank(locationAddress)) {
            return SaResult.error("当前用户没有分配项目或者仓库地址，不能查询！");
        }

        //        根据材料名查询
        MPJLambdaWrapper<MaterialIn>wrapperByMaterialName=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("material_name",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);
        List<MaterialIn> materialInListByMaterialName =list(wrapperByMaterialName);
        if (!materialInListByMaterialName.isEmpty()){
            finalResultList.addAll(materialInListByMaterialName);
        }

        //        根据创建人名查询
        MPJLambdaWrapper<MaterialIn>wrapperByCreateBy=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("create_by",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);

        List<MaterialIn> materialInListByCreateBy =list(wrapperByCreateBy);
        if (!materialInListByCreateBy.isEmpty()){
            finalResultList.addAll(materialInListByCreateBy);
        }


//    根据最后修改人查询

        MPJLambdaWrapper<MaterialIn>wrapperByLastUpdateBy=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("last_update_by",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);
        List<MaterialIn>materialInListByLastUpdateBy = list(wrapperByLastUpdateBy);
        if (!materialInListByLastUpdateBy.isEmpty()){
            finalResultList.addAll(materialInListByLastUpdateBy);
        }
        //    根据品牌查询

        MPJLambdaWrapper<MaterialIn>wrapperByBrand=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("brand",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);
        List<MaterialIn> materialInListByBrand = list(wrapperByBrand);
        if (!materialInListByBrand.isEmpty()){
            finalResultList.addAll(materialInListByBrand);
        }

        //    根据encode查询
        MPJLambdaWrapper<MaterialIn>wrapperByEncode=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("encode",name.toUpperCase())
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);
        List<MaterialIn> materialInListByEncode = list(wrapperByEncode);

        if (!materialInListByEncode.isEmpty()){
            finalResultList.addAll(materialInListByEncode);
        }

        //    根据typeName查询
        MPJLambdaWrapper<MaterialIn>wrapperByTypeName=new MPJLambdaWrapper<MaterialIn>()
                .selectAll(MaterialIn.class)
                .like("type_name",name)
//                下面的都是分页连接查询的普通步骤了
                .eq(!PublicTools.checkLoginRole(),MaterialIn::getWarehouse,locationAddress);
        List<MaterialIn> materialInListByTypeName = list(wrapperByTypeName);

        if (!materialInListByTypeName.isEmpty()){
            finalResultList.addAll(materialInListByTypeName);
        }


        List<MaterialIn>materialIns=new ArrayList<>(finalResultList);
        return SaResult.data((long)materialIns.size());
    }



    private MaterialInDto checkDto(MaterialInDto materialInDto){
//        encode
        String materialInEncodeTrim = StrUtil.trim(materialInDto.getEncode());
        if (StrUtil.isBlank(materialInEncodeTrim)) {
            materialInDto.setEncode(null);
        }else {
            materialInDto.setEncode(materialInEncodeTrim);
        }


        String materialNameTrim = StrUtil.trim(materialInDto.getMaterialName());
        if (StrUtil.isBlank(materialNameTrim)) {
            materialInDto.setMaterialName(null);
        }
        else {
            materialInDto.setMaterialName(materialNameTrim);
        }


        String materialBrandTrim = StrUtil.trim(materialInDto.getBrand());
        if (StrUtil.isBlank(materialBrandTrim)) {materialInDto.setBrand(null);}
        else {
            materialInDto.setBrand(materialBrandTrim);
        }


        String materialModelTrim = StrUtil.trim(materialInDto.getModel());
        if (StrUtil.isBlank(materialModelTrim)) {
            materialInDto.setModel(null);
        }
        else {
            materialInDto.setModel(materialModelTrim);
        }



        String materialWarehouseTrim = StrUtil.trim(materialInDto.getWarehouse());
        if (StrUtil.isBlank(materialWarehouseTrim)) {materialInDto.setWarehouse(null);}
        else {
            materialInDto.setWarehouse(materialWarehouseTrim);
        }


        String materialReceiveProjectTrim = StrUtil.trim(materialInDto.getReceiveProject());
        if (StrUtil.isBlank(materialReceiveProjectTrim)) {materialInDto.setReceiveProject(null);}
        else {
            materialInDto.setReceiveProject(materialReceiveProjectTrim);
        }

//     todo  描述，如果是""，还是需要设置为null，其它的serviceImpl也应该要这样子改一下
        String materialDescriptionTrim = StrUtil.trim(materialInDto.getDescription());
        if (StrUtil.isBlank(materialDescriptionTrim)) {materialInDto.setDescription("");}


        return materialInDto;

    }

    @Transactional
    public void fileOperation(String encode, MultipartFile[] materialPhotoList, HttpServletRequest request) {

//        创建一个materialPhoto集合作为向数据库写数据的容器
        List<MaterialInPhotoDto> materialInPhotoDtoList = new ArrayList<>();
//        创建日期目录
        String format = sdf.format(new Date());
//        详细目录名是date,存储materialPhoto的目录，日期目录，encode目录


        String realPath = fileLocation + materialInPhotoPath + format + encode;
//        创建文件对象
        File folder = new File(realPath);
//        定义全网络路径
        String url;
//        创建目录
        if (!folder.exists()) {
            folder.mkdirs();
        }
//        把前端传进来的文件列表遍历，并写进硬盘中，同时写入数据库中
        for (MultipartFile multipartFile : materialPhotoList) {
            MaterialInPhotoDto materialInPhotoDto=new MaterialInPhotoDto();
//            获取文件的原始文件名，并取得文件后缀名，如.jpg
            String originalFilename = multipartFile.getOriginalFilename();
            int i = 0;
            if (originalFilename != null) {
                i = originalFilename.lastIndexOf(".");
            }
            String substring;
            String newFileName;




            if (originalFilename != null) {
//             把截取文件名的后缀  “.jpg”
                substring = originalFilename.substring(i).toLowerCase();
//            重新拼接文件名加.jpg，前缀是登录名，如登录名为eric，整照片的全名就是eric.jpg
//            为避免文件名出行由于菜单名称相同，而相同造成覆盖，采用了一个7位的随机字符串拼接
                newFileName = RandomUtil.randomString(4).toUpperCase() +substring;
//            }
                try {
//                    通过transferTo方法，把文件写入磁盘
//                    multipartFile.transferTo(new File(folder, newFileName));
                    FileUtils.copyInputStreamToFile(multipartFile.getInputStream(),new File(folder, newFileName));



//
//                    图片文件的最终路径是ServerBASEURL.BASEURL+url，这里只是录入相对路径，这样无论数据放在那个服务器上，都可以访问到图片
//                     ServerBASEURL.BASEURL + materialInPhotoPath+ format +encode+"/"+ newFileName;
                    url = materialInPhotoPath+ format +encode+"/"+ newFileName;
//                    把url,encode,equipmentPhotoDto写入equipmentPhotoDto对象相应字段中





                    materialInPhotoDto.setPhotoUrl(url);
                    materialInPhotoDto.setMaterialInEncode(encode);
                    materialInPhotoDtoList.add(materialInPhotoDto);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
//        把materialPhotoDto列表转换为materialPhoto列表
        List<MaterialInPhoto> materialInPhotoList = BeanUtil.copyToList(materialInPhotoDtoList, MaterialInPhoto.class);
//        写入数据库
        materialInPhotoService.saveBatch(materialInPhotoList);
    }

}
